﻿#region [===== Using =====]
using System;
using System.Web.UI;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Workflow;
#endregion

namespace TPG.SharePoint.Workflow
{
    /// <summary>
    /// Serves as a base class for workflow pages which are
    /// accessible to the users of the workflow.
    /// </summary>
    public abstract class ListWorkflowPage
        : Page, IWorkflowPage
    {
        #region [===== Fields =====]
        SPWorkflowTemplate _workflowTemplate;
        SPWorkflowAssociation _workflowAssociation;
        WorkflowMetaData _metaData;
        #endregion 

        #region [===== Properties =====]
        /// <summary>
        /// Gets a value indicating the type of MasterPage to load for the 
        /// workflow form.
        /// </summary>
        public MasterPageMode MasterPageMode
        {
            get
            {
                return (MasterPageMode?)ViewState["MasterPageMode"] ??
                    MasterPageMode.Application;
            }
            set { ViewState["MasterPageMode"] = value; }
        }

        /// <summary>
        /// Gets a value indicating whether the form is being loaded and 
        /// accessed for the first time.
        /// </summary>
        /// <remarks>
        /// This value is similar to the 
        /// <see cref="System.Web.UI.Page.IsPostBack" /> property. However,
        /// some workflow forms are loaded as the result of a client postback 
        /// request. For these forms the IsPostBack property does not return 
        /// a value that can be used to initialize the form once, since it will
        /// always return true.
        /// </remarks>
        public bool IsInitialLoad
        {
            get { return IsPostBack == false; }
        }
        /// <summary>
        /// Gets the <see cref="SPWorkflowTemplate"/> which serves as the
        /// template for the workflow.
        /// </summary>
        public SPWorkflowTemplate WorkflowTemplate
        {
            get { return WorkflowTemplateInternal; }
        }

        /// <summary>
        /// Gets the <see cref="SPWorkflowAssociation"/> which defines the
        /// association between the workflow template and container to which 
        /// the workflow is applied.
        /// </summary>
        public SPWorkflowAssociation WorkflowAssociation
        {
            get { return WorkflowAssociationInternal; }
        }

        /// <summary>
        /// Gets an object representing the metadata for the workflow form.
        /// </summary>
        /// <remarks>
        /// The metadata for a workflow form consists of properties such as 
        /// the target list, list item, site object or the page-type of the
        /// form.
        /// </remarks>
        public WorkflowMetaData WorkflowMetaData
        {
            get { return MetaDataInternal; }
        }
        
        /// <summary>
        /// Gets the <see cref="SPWeb" /> object in which the 
        /// current workflow page is executing.
        /// </summary>
        protected SPWeb Web
        {
            get { return SPContext.Current.Web; }
        }

        /// <summary>
        /// Gets the <see cref="SPList" /> object with which
        /// the workflow is associated.
        /// </summary>
        protected SPList List
        {
            get { return SPContext.Current.List; }
        }
        // The SPWorkflowTemplate is exposed as an internal field
        // to allow the object to be used by the hosted control
        // framework, without the need to typecast to IWorkflowPage
        // Note that end-users can access this field using the 
        // IWorkflowPage interface.
        internal SPWorkflowTemplate WorkflowTemplateInternal
        {
            get
            {
                if (_workflowTemplate == null)
                {
                    _workflowTemplate = GetWorkflowTemplate();
                }
                return _workflowTemplate;
            }
        }

        // The SPWorkflowAssociation is exposed as an internal field
        // to allow the object to be used by the hosted control
        // framework, without the need to typecast to IWorkflowPage
        // Note that end-users can access this field using the 
        // IWorkflowPage interface.
        internal SPWorkflowAssociation WorkflowAssociationInternal
        {
            get
            {
                if (_workflowAssociation == null)
                {
                    _workflowAssociation = GetWorkflowAssociation();
                }
                return _workflowAssociation;
            }
        }
        // The SPWorkflowTemplate is exposed as an internal field
        // to allow the object to be used by the hosted control
        // framework, without the need to typecast to IWorkflowPage
        // Note that end-users can access this field using the 
        // IWorkflowPage interface.
        internal WorkflowMetaData MetaDataInternal
        {
            get
            {
                if (_metaData == null)
                {
                    _metaData = GetMetaData();
                }
                return _metaData;
            }
        }
        #endregion

        #region [===== Constructor =====]
        /// <summary>
        /// Intializes a new instance of the <see cref="ListWorkflowPage" /> 
        /// class.
        /// </summary>
        protected ListWorkflowPage()
        {
        }
        #endregion

        #region [===== Internal methods =====]
        // Loads the SPWorkflowAssociation using a workflow page 
        // specific context.
        // Note that this method should not cache the returned value,
        // since this class already performs caching of the field.
        internal abstract SPWorkflowAssociation GetWorkflowAssociation();
        // Loads the SPWorkflowTemplate using a workflow page 
        // specific context.
        // Note that this method should not cache the returned value,
        // since this class already performs caching of the field.
        internal abstract SPWorkflowTemplate GetWorkflowTemplate();
        // Loads the WorkflowMetaData using a workflow page 
        // specific context.
        // Note that this method should not cache the returned value,
        // since this class already performs caching of the field.
        internal abstract WorkflowMetaData GetMetaData();
        #endregion 

        #region [===== Protected methods =====]
        /// <summary>
        /// Initializes the <see cref="MasterPage" /> used by 
        /// the workflow form.
        /// </summary>
        /// <param name="e">An <see cref="EventArgs"/> object
        /// representing event data.</param>
        protected override void OnPreInit(EventArgs e)
        {
            // update the master page file, if needed
            switch (MasterPageMode)
            {
//                case MasterPageMode.Application:
  //                  MasterPageFile = "/_layouts/application.master";
    //                break;
                case MasterPageMode.Site:
                    MasterPageFile = SPContext.Current.Web.MasterUrl;
                    break;
            }

            base.OnPreInit(e);
        }
        #endregion
    }
}
